package cn.topcodes.tcsf.wechat.service;

import cn.topcode.unicorn.utils.StringUtil;
import cn.topcode.unicorn.wxsdk.WXContext;
import cn.topcode.unicorn.wxsdk.material.MaterialInvoker;
import cn.topcode.unicorn.wxsdk.material.dto.UploadForeverMaterialResult;
import cn.topcodes.tcsf.admin.commons.generic.GenericService;
import cn.topcodes.tcsf.wechat.domain.entity.WechatMp;
import cn.topcodes.tcsf.wechat.domain.entity.WechatVideo;
import cn.topcodes.tcsf.wechat.service.utils.BeanUtils;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.*;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

/**
 * 视频素材 服务
 * @author xw
 * @date 2017-12-22 23:02:24
 */
@Service
@Transactional(readOnly = true)
public class WechatVideoServiceImpl extends GenericService<WechatVideo> implements WechatVideoService {

    @Autowired
    private WechatMpService wechatMpService;

    private MaterialInvoker invoker = WXContext.getMaterialInvoker();

    @Autowired
    private WechatFileService wechatFileService;

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void upload(String mpId, WechatVideo entity, File file) {

        entity.setUrl("/video/" + file.getName());
        long length = wechatFileService.getDuration(file);
        entity.setLength(LocalTime.ofSecondOfDay(length / 1000).format(DateTimeFormatter.ofPattern("mm:ss")));

        UploadForeverMaterialResult result = invoker.uploadForeverVideoMaterial(mpId, entity.getTitle(), entity.getIntroduce(), file);
        if (result.getErrcode() == 0) {
            entity.setMediaId(result.getMediaId());
            WechatMp wechatMp = wechatMpService.findWechatMpByMpId(mpId);
            entity.setWechatMpId(wechatMp.getId());
            this.create(entity);
        } else {
            throw new IllegalArgumentException("errcode: " + result.getErrcode() + ", errmsg: " + result.getErrmsg());
        }
    }

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void upload(WechatVideo entity, File file) {
        this.upload(wechatMpService.getDefaultMpId(), entity, file);
    }

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public WechatVideo setCover(Long id, String data) {
        WechatVideo video = this.findOne(id);
        if (video == null) {
            return video;
        }

        // 去掉头部信息
        data = data.replace("data:image/png;base64,", "");
        data = data.replaceAll(" ", "+");

        // 解码并得到图片的二进制数据
        Base64 base64 = new Base64();
        byte[] imgData = base64.decode(data);

        // 生成图片
        File file = null;
        String coverName = null;
        boolean backupIsSuccess = false;
        try {
            String videoSavePath = wechatFileService.getVideoStoragePath();
            String coverUrl = video.getCoverUrl();
            String videoName = wechatFileService.getNameByUrl(video.getUrl(), "/");
            String fileName = null;
            coverName = wechatFileService.getNameByUrl(coverUrl, "/");

            if (StringUtil.isNotBlank(coverUrl)) {
                // 先把原先的缩略图进行备份
                backupIsSuccess =
                        WechatFileService.backupFile(wechatFileService.getVideoStoragePath() + "/" + coverName);
                fileName = wechatFileService.getNameByUrl(coverUrl, "/");
                file = wechatFileService.rename(new File(videoSavePath, fileName), null);
            } else {
                fileName = wechatFileService.getName(videoName) + ".png";
                file = new File(videoSavePath, fileName);
            }
            if (!file.exists()) {
                file.createNewFile();
            }
            OutputStream out = new FileOutputStream(file);
            out.write(imgData);
            out.flush();
            out.close();
            video.setCoverUrl("/video/" + file.getName());
            String mpId = wechatMpService.getMpId(video.getWechatMpId());
            UploadForeverMaterialResult result = invoker.uploadForeverThumbMaterial(mpId, file);
            if (result.getErrcode() == 0) {
                if (backupIsSuccess) {
                    wechatFileService.deleteFile(
                            WechatFileService.FILE_TYPE_THUMB, coverName + WechatFileService.BACKUP_SUFFIX);
                }

                String mediaId = video.getThumbMediaId();
                if (StringUtil.isNotBlank(mediaId)) {
                    invoker.deleteForeverMaterial(mpId, mediaId);
                }
                video.setThumbMediaId(result.getMediaId());
                video.setThumbUrl(result.getUrl());
                super.update(video);
            } else {
                throw new IllegalArgumentException("errcode: " + result.getErrcode() + ", errmsg: " + result.getErrmsg());
            }
        } catch (Exception e) {
            if (file.exists()) {
                file.delete();
            }
            if (backupIsSuccess) {
                // 微信api接口达到每日上限，恢复原来的缩略图
                WechatFileService.restoreFile(
                        wechatFileService.getVideoStoragePath() + "/" +
                        coverName + WechatFileService.BACKUP_SUFFIX);
            }
            e.printStackTrace();
        }
        return video;
    }

    @Override
    @Transactional(readOnly = false, rollbackFor = Exception.class)
    public void update(WechatVideo video) {
        WechatVideo v = this.findOne(video.getId());
        if (v != null) {
            BeanUtils.copyProperties(v, video);
            super.update(v);
        }
    }

    @Override
    @Transactional(readOnly = false)
    public WechatVideo delete(Long id) {
        WechatVideo video = this.findOne(id);
        if (video != null) {
            String mpId = wechatMpService.getMpId(video.getWechatMpId());
            String coverUrl = video.getCoverUrl();
            wechatFileService.deleteFile(
                    WechatFileService.FILE_TYPE_THUMB, wechatFileService.getNameByUrl(coverUrl, "/"));
            invoker.deleteForeverMaterial(mpId, video.getThumbMediaId());
            String url = video.getUrl();
            wechatFileService.deleteFile(
                    WechatFileService.FILE_TYPE_VIDEO, wechatFileService.getNameByUrl(url, "/"));
            invoker.deleteForeverMaterial(mpId, video.getMediaId());
            return super.delete(id);
        }
        return null;
    }
}
